from __future__ import annotations

import os
import re
from typing import Set, Dict

from .base import BaseLanguageDependencyStrategy
from ...utils_module.language_utils import language_to_extensions


class JavaDependencyStrategy(BaseLanguageDependencyStrategy):
    LANGUAGE = 'java'

    def __init__(self, logger=None):
        super().__init__(logger)
        self._import_patterns = [
            re.compile(r'^import\s+([\w\.\*]+);', re.MULTILINE),
            re.compile(r'^import\s+static\s+([\w\.\*]+);', re.MULTILINE),
        ]

    def extract_imports(self, content: str) -> Set[str]:
        imports: Set[str] = set()
        for pattern in self._import_patterns:
            imports.update(pattern.findall(content))
        return imports

    def resolve_import(
        self,
        import_name: str,
        source_file: str,
        module_to_files: Dict[str, Set[str]],
    ) -> Set[str]:
        resolved: Set[str] = set()
        source_dir = os.path.dirname(source_file)

        if import_name in module_to_files:
            resolved.update(module_to_files[import_name])

        for candidate in self._generate_possible_paths(import_name, source_dir):
            if os.path.exists(candidate):
                resolved.add(os.path.abspath(candidate))

        return resolved

    def extract_module_name(self, file_path: str):
        file_name = os.path.basename(file_path)
        file_stem, _ = os.path.splitext(file_name)

        try:
            with open(file_path, 'r', encoding='utf-8') as handle:
                content = handle.read(1000)
        except Exception:
            return file_stem

        package_match = re.search(r'^package\s+([\w\.]+)', content, re.MULTILINE)
        if package_match:
            return f"{package_match.group(1)}.{file_stem}"

        return file_stem

    def _generate_possible_paths(self, import_name: str, base_dir: str):
        extensions = set(language_to_extensions('java'))
        path_parts = import_name.replace('.', os.sep).split(os.sep)

        for ext in extensions:
            yield os.path.join(base_dir, *path_parts) + ext
